package top.lixunda.ecommerce.server.good.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.business.BaseServiceImpl;
import top.lixunda.ecommerce.server.business.api.entity.cache.CacheStore;
import top.lixunda.ecommerce.server.business.api.entity.cache.CacheStoreUser;
import top.lixunda.ecommerce.server.good.api.entity.db.FrequentlyQuestionDO;
import top.lixunda.ecommerce.server.good.api.entity.db.GoodsDO;
import top.lixunda.ecommerce.server.good.api.entity.dto.QuestionChangeDTO;
import top.lixunda.ecommerce.server.good.api.entity.dto.QuestionInsertDTO;
import top.lixunda.ecommerce.server.good.mapper.FrequentlyQuestionMapper;
import top.lixunda.ecommerce.server.good.service.IFrequentlyQuestionService;
import top.lixunda.ecommerce.server.good.service.IGoodsService;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * FQA 常问问题数据表，目前由商家进行设置 服务实现类
 * </p>
 *
 * @author Xumda
 * @since 2020-01-06
 */
@Slf4j
@Service
public class FrequentlyQuestionServiceImpl
        extends BaseServiceImpl<FrequentlyQuestionMapper, FrequentlyQuestionDO>
        implements IFrequentlyQuestionService {

    private final IGoodsService goodsService;

    @Autowired
    public FrequentlyQuestionServiceImpl(IGoodsService goodsService) {
        this.goodsService = goodsService;
    }

    /**
     * 插入一个FQA
     *
     * @param questionInsertDtoList FQA数据
     * @return 插入数量
     */
    @Override
    public Integer saveFqas(List<QuestionInsertDTO> questionInsertDtoList) {
        if (ObjectValidators.isEmpty(questionInsertDtoList)) {
            throw getAppException("参数不能为空");
        }
        CacheStore cacheStore = currentStoreCacheNotNull();
        CacheStoreUser cacheStoreUser = currentStoreUserCacheNotNull();
        List<FrequentlyQuestionDO> insertDoList = new ArrayList<>(questionInsertDtoList.size());
        LocalDateTime time = LocalDateTime.now();
        for (QuestionInsertDTO dto : questionInsertDtoList) {
            if (ObjectValidators.isEmpty(dto)) {
                throw getAppException("参数不能为空");
            }
            FrequentlyQuestionDO insertDo = new FrequentlyQuestionDO();
            insertDo.setStoreId(cacheStore.getId());
            insertDo.setGoodId(dto.getId() == null || dto.getId() <= 0 ? null : dto.getId());
            insertDo.setQuestion(dto.getQuestion());
            insertDo.setAnswer(dto.getAnswer());
            insertDo.setCreateTime(time);
            insertDo.setUpdateTime(time);
            insertDo.setCreateUserId(cacheStoreUser.getAccount());
            insertDo.setUpdateUserId(cacheStoreUser.getAccount());
            insertDo.setCreateUserName(cacheStoreUser.getName());
            insertDo.setUpdateUserName(cacheStoreUser.getName());
            insertDoList.add(insertDo);
        }
        if (insertDoList.size() == 1) {
            this.save(insertDoList.get(0));
        } else {
            this.saveBatch(insertDoList);
        }
        return insertDoList.size();
    }

    /**
     * 查询商品所有FQA
     *
     * @param ids 商品id
     * @return FQA列表，不一定是商品特有的，也可能是店铺共有的
     */
    @Override
    public List<FrequentlyQuestionDO> queryAllFqaByGoodIds(List<Integer> ids) {
        if (ObjectValidators.isEmpty(ids)) {
            throw getAppException("商品id不能为空");
        }
        // 获取商品店铺信息
        List<GoodsDO> goodsDoList = null;
        if (ids.size() == 1) {
            GoodsDO goodsDO = goodsService.getById(String.valueOf(ids.get(0)));
            if (goodsDO != null) {
                goodsDoList = Collections.singletonList(goodsDO);
            }
        } else {
            goodsDoList = goodsService.list(
                    new LambdaQueryWrapper<GoodsDO>()
                            .in(GoodsDO::getId, ids)
                            .select(GoodsDO::getId, GoodsDO::getStoreId));
        }

        if (ObjectValidators.isEmpty(goodsDoList)) {
            return Collections.emptyList();
        }

        // 组装店铺信息
        List<Integer> storeIdList = goodsDoList.stream()
                .map(GoodsDO::getId)
                .distinct()
                .collect(Collectors.toList());

        if (ObjectValidators.isEmpty(storeIdList)) {
            log.error("商品店铺id为空");
            throw getAppException("系统错误，店铺信息为空");
        }

        return this.list(new LambdaQueryWrapper<FrequentlyQuestionDO>()
                .in(FrequentlyQuestionDO::getGoodId, ids)
                .or(wrapper -> wrapper.isNull(FrequentlyQuestionDO::getGoodId)
                        .in(FrequentlyQuestionDO::getStoreId, storeIdList)));
    }

    /**
     * 查询店铺所有FQA
     *
     * @param ids 店铺id
     * @return FQA列表
     */
    @Override
    public List<FrequentlyQuestionDO> queryAllFqaByStoreIds(List<Integer> ids) {
        if (ObjectValidators.isEmpty(ids)) {
            throw getAppException("店铺id不能为空");
        }
        return this.list(new LambdaQueryWrapper<FrequentlyQuestionDO>()
                .in(FrequentlyQuestionDO::getStoreId, ids));
    }

    /**
     * 根据id查询FQA
     *
     * @param ids FQA的id
     * @return FQA列表
     */
    @Override
    public List<FrequentlyQuestionDO> queryFqaByIds(List<Integer> ids) {
        if (ObjectValidators.isEmpty(ids)) {
            throw getAppException("FQA编号不能为空");
        }
        return this.list(new LambdaQueryWrapper<FrequentlyQuestionDO>()
                .in(FrequentlyQuestionDO::getId, ids));
    }

    /**
     * 根据FQA的id更改FQA数据
     *
     * @param questionChangeDTO FQA的id及更改数据
     * @return 更改后的FQA数据
     */
    @Override
    public FrequentlyQuestionDO changeQuestionById(QuestionChangeDTO questionChangeDTO) {
        if (ObjectValidators.isEmpty(questionChangeDTO)) {
            throw getAppException("参数不能为空");
        }
        CacheStoreUser cacheStoreUser = currentStoreUserCacheNotNull();
        CacheStore cacheStore = currentStoreCacheNotNull();

        FrequentlyQuestionDO frequentlyQuestionDO = new FrequentlyQuestionDO();
        frequentlyQuestionDO.setQuestion(questionChangeDTO.getQuestion());
        frequentlyQuestionDO.setAnswer(questionChangeDTO.getAnswer());
        frequentlyQuestionDO.setUpdateUserId(cacheStoreUser.getAccount());
        frequentlyQuestionDO.setUpdateUserName(cacheStoreUser.getName());
        frequentlyQuestionDO.setUpdateTime(LocalDateTime.now());
        boolean success = this.update(frequentlyQuestionDO,
                new LambdaUpdateWrapper<FrequentlyQuestionDO>()
                        .eq(FrequentlyQuestionDO::getId, questionChangeDTO.getId())
                        .eq(FrequentlyQuestionDO::getStoreId, cacheStore.getId()));
        if (!success) {
            log.info("跟新数据失败：{}", frequentlyQuestionDO.toString());
            throw getAppException("更新数据失败");
        }
        return this.getById(questionChangeDTO.getId());
    }

    /**
     * 根据id移除FQA数据
     *
     * @param ids FQA的id
     * @return 移除数量
     */
    @Override
    public Integer removeQuestionById(List<Integer> ids) {
        if (ObjectValidators.isEmpty(ids)) {
            throw getAppException("FQA编号不能为空");
        }
        CacheStoreUser cacheStoreUser = currentStoreUserCacheNotNull();
        CacheStore cacheStore = currentStoreCacheNotNull();
        this.update(new LambdaUpdateWrapper<FrequentlyQuestionDO>()
                .set(FrequentlyQuestionDO::getRemoveTime, LocalDateTime.now())
                .set(FrequentlyQuestionDO::getRemoveUserId, cacheStoreUser.getAccount())
                .set(FrequentlyQuestionDO::getRemoveUserName, cacheStoreUser.getName())
                .in(FrequentlyQuestionDO::getId, ids)
                .eq(FrequentlyQuestionDO::getStoreId, cacheStore.getId()));
        boolean success = this.remove(new LambdaUpdateWrapper<FrequentlyQuestionDO>()
                .in(FrequentlyQuestionDO::getId, ids)
                .eq(FrequentlyQuestionDO::getStoreId, cacheStore.getId()));
        if (!success) {
            throw getAppException("移除FQA数据失败");
        }
        return ids.size();
    }

}
